﻿using Furion.DynamicApiController;
using Furion.RemoteRequest.Extensions;
using FurStudy.Core;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;

namespace FurStudy.Application
{
    public class RemoteRequestService : IDynamicApiController
    {
        private readonly IHttp _http;

        public RemoteRequestService(IHttp http)
        {
            _http = http;
        }

        public async Task GetData()
        {
            var data = await _http.GetXXXAsync();

            // 通过字符串拓展方式

            // 发送Get请求
            var responseGet = await "https://www.furion.pro/get".GetAsync();

            // 发送Post请求
            var responsePost = await "https://www.furion.pro/post".PostAsync();

            // 发送Put请求
            var responsePut = await "https://www.furion.pro/put".PutAsync();

            // 发送Delete请求
            var responseDel = await "https://www.furion.pro/delete".DeleteAsync();

            // 发送Patch请求
            var responsePatch = await "https://www.furion.pro/patch".PatchAsync();

            // 发送Head请求
            var responseHead = await "https://www.furion.pro/head".HeadAsync();

            // 手动指定发送特定请求
            var responseHttpMethod = await "https://www.furion.pro/post".SetHttpMethod(HttpMethod.Post).SendAsync();

            #region 【设置请求地址】

            // await "".SetRequestUrl("https://www.furion.pro/");

            #endregion

            #region 【设置请求方式】

            // await "https://www.furion.pro/post".SetHttpMethod(HttpMethod.Get);

            #endregion

            #region 【设置地址模板（模板替换区分大小写）】

            // 字典方式
            // await "https://www.furion.pro/post/{id}?name={name}&id={p.Id}".SetTemplates(new Dictionary<string, object> {
            //   { "id", 1 },
            //   { "name", "Furion" },
            //   { "p.Id", new Person { Id = 1 } }
            // });
            // 对象/匿名对象方式
            // await "https://www.furion.pro/post/{id}?name={name}".SetTemplates(new
            // {
            //   id = 1,
            //   name = "Furion"
            // });

            #endregion

            #region 【设置请求报文头】

            // 字典方式
            //await "".SetHeaders(new Dictionary<string, object> {
            //    { "Authorization", "Bearer 你的token"},
            //    { "X-Authorization", "Bearer 你的刷新token"}
            //});
            // 对象/匿名对象方式
            //await "https://www.furion.pro/post".SetHeaders(new
            //{
            //    Authorization = "Bearer 你的token"
            //});

            #endregion

            #region 【设置URL地址参数（最终输出格式为：https://www.furion.pro/get?id=1&name=Furion）】

            // 字典方式
            //await "https://www.furion.pro/get".SetQueries(new Dictionary<string, object> {
            //    { "id", 1 },
            //    { "name", "Furion"}
            //});

            //// 对象/匿名对象方式
            //await "https://www.furion.pro/get".SetQueries(new
            //{
            //    id = 1,
            //    name = "Furion"
            //});

            #endregion

            #region 【设置请求客户端】

            // await "get".SetClient("github");

            #endregion

            #region 【设置Body参数】

            // 传入对象
            //await "https://www.furion.pro/api/user/add".SetBody(new User { Id = 1, Name = "Furion" });

            //// 配置 Content-Type
            //await "https://www.furion.pro/api/user/add".SetBody(new { Id = 1, Name = "Furion" }, "application/json");

            //// 设置 Encoding 编码
            //await "https://www.furion.pro/api/user/add".SetBody(new User { Id = 1, Name = "Furion" }, "application/json", Encoding.UTF8);

            //// 处理 application/x-www-form-urlencoded 请求
            //await "https://www.furion.pro/api/user/add".SetBody(new Dictionary<string, object> {
            //    { "Id", 1 },
            //    { "Name", "Furion"}
            //}, "application/x-www-form-urlencoded");

            //// 处理 application/xml、text/xml
            //await "https://www.furion.pro/api/user/add".SetBody("<SomeDto><SomeTag>somevalue</SomeTag></SomeDto>", "application/xml");

            // 注：如果请求Content-Type设置为application/x-www-form-urlencoded类型，那么底层自动将数据进行UrlEncode编码处理，无需外部处理

            #endregion

            #region 【设置Content-Type】

            // await "https://www.furion.pro/post".SetContentType("application/json");

            #endregion

            #region 【设置内容编码】

            // await "https://www.furion.pro/post".SetContentEncoding(Encoding.UTF8);

            #endregion

            #region 【设置JSON序列化提供程序】

            // Furion默认情况下采用System.Text.Json进行JSON序列化处理，如需设置第三方JSON提供器，则可以通过以下配置：

            //// 泛型方式
            //await "https://www.furion.pro/api/user/add".SetJsonSerialization<NewtonsoftJsonSerializerProvider>();

            //// 非泛型方式
            //await "https://www.furion.pro/api/user/add".SetJsonSerialization(typeof(NewtonsoftJsonSerializerProvider));

            //// 添加更多配置
            //await "https://www.furion.pro/api/user/add".SetJsonSerialization<NewtonsoftJsonSerializerProvider>(new JsonSerializerSettings
            //{

            //});

            #endregion

            #region 【启用Body参数验证】

            //await "https://www.furion.pro/api/user/add".SetValidationState();

            // 设置不验证 null 值
            //await "https://www.furion.pro/api/user/add".SetValidationState(includeNull: true);

            // 支持类中 [Required] 等完整模型验证特性。

            #endregion

            #region 【请求拦截】

            //await "https://www.furion.pro/".OnRequesting(req => {
            //    // req 为 HttpRequestMessage 对象
            //    // 追加更多参数
            //    req.AppendQueries(new Dictionary<string, object> {
            //        { "access_token", "xxxx"}
            //    });
            // });

            // 支持多次拦截

            #endregion

            #region 【HttpClient拦截】

            //await "https://www.furion.pro/".OnClientCreating(client => {
            //    // client 为 HttpClient 对象
            //    client.Timeout = 30000; // 设置超时时间
            //});

            // 支持多次拦截

            #endregion

            #region 【成功请求拦截】

            //await "https://www.furion.pro/".OnResponsing(res => {
            //    // res 为 HttpResponseMessage 对象
            //});

            // 支持多次拦截

            #endregion

            #region 【请求异常拦截】

            //await "https://www.furion.pro/".OnException((res, errors) => {
            //    // res 为 HttpResponseMessage 对象
            //});

            // 支持多次拦截

            #endregion

            // 各种返回值处理

            // HttpResponseMessage
            var res = await "https://www.furion.pro/".GetAsync();

            // Stream
            var steam = await "https://www.furion.pro/".GetAsStreamAsync();

            // T
            var user = await "https://www.furion.pro/".GetAsAsync<User>();

            // String
            var str = "https://www.furion.pro/".GetAsStringAsync();

            #region 【设置Byte[]类型】

            // 有时候我们需要上传文件，需要设置Content-Type为multipart/form-data类型，如：

            // bytes 可以通过 File.ReadAllBytes(文件路径) 获取
            var bytes = File.ReadAllBytes("");
            var resByte = await "https://www.furion.pro/upload".SetBody(new { id = 1, name = "Furion" }, "multipart/form-data")
                                                           .SetBodyBytes(("键", bytes, "文件名")).PostAsync();

            #endregion

            #region 【设置IServiceProvider】

            // 有时候我们需要构建一个作用域的IServiceProvider，这时只需要设置即可：

            //var resIService = await "https://www.furion.pro/upload".SetRequestScoped(services);

            #endregion

            #region 【设置Timeout超时时间】

            //var res = await "https://www.furion.pro/upload".SetClientTimeout(10); // 单位秒

            #endregion
        }
    }
}
